/*
 * Copyright 2010 Lars Heuer (heuer[at]semagia.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.semagia.mio.pymio;

import java.io.IOException;

import org.python.core.Py;
import org.python.core.PyFile;
import org.python.core.PyFileReader;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.util.PythonInterpreter;


import com.semagia.mio.Context;
import com.semagia.mio.IDeserializer;
import com.semagia.mio.IDeserializerFactory;
import com.semagia.mio.MIOException;
import com.semagia.mio.Source;
import com.semagia.mio.Syntax;
import com.semagia.mio.base.AbstractDeserializer;

/**
 * 
 * 
 * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
 * @version $Rev: 353 $ - $Date: 2010-08-14 14:22:44 +0000 (Sat, 14 Aug 2010) $
 */
abstract class AbstractPyMioDeserializerFactory implements IDeserializerFactory {

    private static final String _PATH_TO_MIO_CORE = "/projekte/mio/sandbox/pymio/lib/semagia-mio-0.9.5.jar";
    private static final String _PATH_TO_MIO = "/projekte/mio/sandbox/pymio/pymio";
    
    private final Syntax _syntax;
    private final PyObject _factory;
    private final PyObject _sourceClass;
    private final PyObject _mapHandlerClass;

    public AbstractPyMioDeserializerFactory(final Syntax syntax, final String module) {
        _syntax = syntax;
        final PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.exec("import sys; " +
                         //TODO: This should be unnecessary
                         "sys.path.append('" + _PATH_TO_MIO_CORE + "'); " +
                         "sys.path.append('" + _PATH_TO_MIO + "'); " +
                         "from mio.reader import " + module + " as factory; " +
                         "from tm.mio import Source;" +
                         "from tm.mio.handler import MIOHandlerToJava;");
        _factory = interpreter.get("factory");
        _sourceClass = interpreter.get("Source");
        _mapHandlerClass = interpreter.get("MIOHandlerToJava");
    }

    /* (non-Javadoc)
     * @see com.semagia.mio.IDeserializerFactory#getDeserializer()
     */
    @Override
    public IDeserializer createDeserializer() {
        return new PyMioDeserializer(_factory.invoke("create_deserializer"),
                                     _sourceClass, 
                                     _mapHandlerClass); 
    }

    /* (non-Javadoc)
     * @see com.semagia.mio.IDeserializerFactory#getSyntax()
     */
    @Override
    public Syntax getSyntax() {
        return _syntax;
    }


    /**
     * 
     * 
     */
    private static final class PyMioDeserializer extends AbstractDeserializer {

        private static final String[] _SRC_KW = new String[] {"iri", "file", "data", "encoding"};
        private final PyObject _pyDeserializer;
        private final PyObject _srcClass;
        private final PyObject _mapHandlerClass;

        public PyMioDeserializer(final PyObject pyDeserializer, PyObject srcClass, PyObject mapHandlerClass) {
            _pyDeserializer = pyDeserializer;
            _srcClass = srcClass;
            _mapHandlerClass = mapHandlerClass;
        }

        @Override
        protected void doParse(final Source src) throws IOException, MIOException {
            try {
                final String iri = src.getBaseIRI() != null ? src.getBaseIRI()
                        : src.getIRI();
                System.out.println("IRI: " + iri);
                final PyObject pyIRI = iri != null ? new PyString(iri) : null;
                final PyObject pyFile = src.getCharacterStream() != null 
                                            ? new PyFileReader(src.getCharacterStream()) 
                                            : null;
                final PyObject pyData = src.getByteStream() != null 
                                            ? new PyFile(src.getByteStream())
                                            : null;
                final PyObject pyEncoding = src.getEncoding() != null 
                                            ? new PyString(src.getEncoding())
                                            : null;
                                                
                final PyObject pySrc = _srcClass.__call__(new PyObject[] {pyIRI, 
                                                          pyFile, 
                                                          pyData, 
                                                          pyEncoding}, _SRC_KW);
                _pyDeserializer.__setattr__("handler", _mapHandlerClass.__call__(Py.java2py(_handler)));
                _pyDeserializer.__setattr__("subordinate", Py.java2py(Boolean.valueOf(_isSubordinate)));
                _pyDeserializer.invoke("parse", pySrc);
            }
            finally {
                //_interpreter.cleanup();
            }
        }

        @Override
        public Context getContext() {
            return null;
        }

        @Override
        public void setContext(Context arg0) {
        }

        @Override
        public Object getProperty(String arg0) {
            return null;
        }

        @Override
        public void setProperty(String arg0, Object arg1) {
        }

    }
}
